package org.musicsweet.util;


import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;

//指定某个类是容器的bean
@Component
public class RedisUtil {
    /**
     * 引用下面的@Bean名称的方式
     * @Resource默认按照名称方式进行bean匹配，@Autowired默认按照类型方式进行bean匹配
     */
    @Resource(name = "redisStringTemplate")
    private RedisTemplate redisTemplate;

    /**
     * 写入缓存  这里的括号里为什么写成key and value的形式呢   应为redis的string--->就是key value的形式
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key, String value) {
        try {
            /**
             * 首先获取到operations这个对象才能对redis进行操作
             * 然后向redis塞取一对键值对
             * 返回true就是数据塞入成功  false则为失败
             */
            ValueOperations<Serializable, String> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 这个方法是根据key获取到缓存对应的value值
     *
     * @param key
     * @return
     */
    public String get(String key) {
        /**
         * 如果有则返回rs（value）没有则返回null
         */
        try {
            ValueOperations<Serializable, String> operations = redisTemplate.opsForValue();
            String rs = operations.get(key);
            return rs;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 写入缓存并设置缓存的有效时间
     *
     * @param key
     * @param value
     * @param expireTime
     * @return
     */
    public boolean setEx(String key, String value, Long expireTime) {
        try {
            ValueOperations<Serializable, String> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            /**
             * 设置一个key给哪个Key设置有效时间    TimeUnit.SECONDS（以秒为计时单位）
             */
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 判断缓存是否有该key
     *
     * @param key
     * @return
     */
    public boolean exist(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 根据key删除对应的value值
     *
     * @param key
     * @return
     */
    public boolean remove(String key) {
        if (exist(key)) {
            return redisTemplate.delete(key);
        }
        return false;
    }

    /**
     * 清除redis默认序列化
     * @param factory
     * @return
     * Spring的@Bean注解用于告诉方法，产生一个Bean对象，然后这个Bean对象交给Spring管理
     */
    @Bean("redisStringTemplate")
    public RedisTemplate<Object,Object> redisStringTemplate(RedisConnectionFactory factory){
        RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        /**
         * 就需要使用到new StringRedisSerializer()
         * 将key 和 value都变为StringRedisSerializer
         */
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}
